package com.egg.mall.service.category.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.egg.common.core.exception.CustomException;
import com.egg.common.mybatis.service.impl.BaseServiceImpl;
import com.egg.common.util.JsonUtil;
import com.egg.common.util.OptionalUtil;
import com.egg.mall.entity.category.CategoryAttribute;
import com.egg.mall.entity.category.Category;
import com.egg.mall.enums.AttributeTypeEnum;
import com.egg.mall.mapper.category.CategoryAttributeMapper;
import com.egg.mall.model.request.AttributeListPut;
import com.egg.mall.service.category.ICategoryAttributeService;
import com.egg.mall.service.category.ICategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @author east
 */
@Slf4j
@Service
public class CategoryAttributeServiceImpl extends BaseServiceImpl<CategoryAttributeMapper, CategoryAttribute> implements ICategoryAttributeService {


    @Autowired
    private ICategoryService categoryService;


    /**
     * 查询分类下属性
     *
     * @param categoryId 分类主键ID
     * @return 属性集合
     */
    @Override
    public List<CategoryAttribute> findByCategoryId(Serializable categoryId) {
        if (ObjectUtil.isEmpty(categoryId)) {
            return Collections.emptyList();
        }
        return findByCategoryId(Arrays.asList(categoryId));
    }

    /**
     * 查询分类下属性
     *
     * @param categoryId 分类主键ID
     * @return 属性集合
     */
    @Override
    public List<CategoryAttribute> findByCategoryId(Collection<? extends Serializable> categoryId) {
        return find(OptionalUtil.build(categoryId), Optional.empty());
    }

    @Override
    public List<CategoryAttribute> find(
            Optional<Collection<? extends Serializable>> categoryId
            , Optional<String> type
    ) {
        if (!categoryId.isPresent()
                && !type.isPresent()
        ) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<CategoryAttribute> qw = buildLambdaQw();
        categoryId.ifPresent(o -> qw.in(CategoryAttribute::getCategoryId, o));
        type.ifPresent(o -> qw.eq(CategoryAttribute::getType, o));
        return list(qw);
    }

    /**
     * 删除分类下的属性
     *
     * @param categoryId 分类主键ID
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void delByCategoryId(Collection<? extends Serializable> categoryId) {
        if (ObjectUtil.isEmpty(categoryId)) {
            return;
        }
        LambdaQueryWrapper<CategoryAttribute> qw = buildLambdaQw();
        qw.in(CategoryAttribute::getCategoryId, categoryId);
        remove(qw);
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public List<Long> put(String categoryId, AttributeListPut param) {
        if (ObjectUtil.isEmpty(categoryId)
                || ObjectUtil.isEmpty(param.getType())
        ) {
            return Collections.emptyList();
        }
        if (AttributeTypeEnum.isInvalid(param.getType())) {
            throw new CustomException("类型无效");
        }
        boolean repeat = param.getAttributes().stream()
                .filter(o1 -> ObjectUtil.isNotEmpty(o1.getName()))
                .anyMatch(o1 -> param.getAttributes().stream()
                        .filter(o2 -> ObjectUtil.isNotEmpty(o2.getName()))
                        .filter(o2 -> Objects.equals(o1.getName(), o2.getName())).count() > 1);
        if (repeat) {
            throw new CustomException("名称重复");
        }
        Category category = categoryService.baseGetById(categoryId);
        List<CategoryAttribute> saveList = new ArrayList<>();
        List<CategoryAttribute> existList = find(OptionalUtil.build(Arrays.asList(category.getId())), OptionalUtil.build(param.getType()));
        List<Long> existIds = existList.stream().map(o -> o.getId()).collect(Collectors.toList());
        param.getAttributes().stream()
                .filter(o -> ObjectUtil.isNotEmpty(o.getName()))
                .forEach(o -> {
                    CategoryAttribute save = JsonUtil.objToObj(o, CategoryAttribute.class);
                    if (!existIds.contains(save.getId())) {
                        save.setId(null);
                    }
                    save.setCategoryId(category.getId());
                    save.setType(param.getType());
                    saveList.add(save);
                });
        this.baseDel(existIds);
        baseSave(saveList);
        return saveList.stream().map(o -> o.getId()).collect(Collectors.toList());
    }


}
